import Vue from 'vue'
import Vuex from 'vuex'
import cloneDeep from 'lodash/cloneDeep'

Vue.use(Vuex)

// 可用于模块的批量导入，类同于import引入同一文件夹下多个文件。
// require.context(directory, useSubdirectories = false, regExp = /^.//);
// 参数： 1. 读取文件的路径 2. 是否遍历文件的子目录 3. 匹配文件的正则表达式
// 返回是一个函数，是该文件夹下的匹配文件的执行环境
// 该函数有三个属性
// 利用webpack中的require获取同级modules文件夹下所有文件名以.js为结尾的上下文
let storeFiles = require.context('./module', true, /\.js$/)

// 动态获取各个模块属性
let getters = {}

// reduce(()=> {total, currentValue, currentIndex, arr}, initValue)
// 参数： 1. 执行每条数据的函数 2. 传递给函数的初始值，可选（以前没发现初始值的妙用-可用于统计个数、去重等）
// 函数的参数
// 1. total            必需。初始值, 或者计算结束后的返回值。如果设置初始值就用初始值，否则就是函数的第一条数据
// 2. currentValue     必需。当前元素
let modules = storeFiles.keys().reduce((module, modulePath) => {
	// 获取js文件名
	let moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
	// 通过storeFiles返回一个module对象{default: {// 文件内容}, _esModule: true}
	let moduleFile = storeFiles(modulePath)
	module[moduleName] = moduleFile.default
	
	// 动态将各个模块的属性映射到getters中
	let moduleData = module[moduleName].state
	for (let key in moduleData) {
		// 判断对象所有属性是否是对象自身的
		if(moduleData.hasOwnProperty(key)){
			getters[moduleName + '_' + key] = () => moduleData[key]
		}
	}
	
	return module
}, {})

let store = new Vuex.Store({
	modules,
	getters,
	mutations: {
		// 重置vuex本地存储状态
		resetStore(state) {
			this.commit('common/SET_DYNAMICMENUROUTES', [])
			this.commit('common/SET_PERMISSIONS', [])
			Object.keys(state).forEach((key) => {
				state[key] = cloneDeep(window.CONFIG['storeState'][key])
			})
		},
		update(state, payload) {
			// 判断是否多层级调用，state中为对象存在的情况，诸如user.info.score = 1
			let nameArr = payload.name.split('.');
			let saveKey = '';
			let len = nameArr.length;
			if (len >= 2) {
				let obj = state[nameArr[0]];
				for (let i = 1; i < len - 1; i++) {
					obj = obj[nameArr[i]];
				}
				obj[nameArr[len - 1]] = payload.value;
			} else {
				// 单层级变量，在state就是一个普通变量的情况
				state[payload.name] = payload.value;
			}
		}
	},
	strict: process.env.NODE_ENV !== 'production'
})

// 保存整站vuex本地储存初始状态
window.CONFIG['storeState'] = cloneDeep(store.state)

export default store